package com.eastfair.certificate.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.eastfair.auth.api.UserAccountServiceFeign;
import com.eastfair.boot.request.PageParams;
import com.eastfair.cache.projectcore.DictionaryCacheKeyBuilder;
import com.eastfair.certificate.dao.BadgeTemplateMapper;
import com.eastfair.certificate.entity.*;
import com.eastfair.certificate.service.BadgeTemplateDetailService;
import com.eastfair.certificate.service.BadgeTemplateService;
import com.eastfair.boot.service.SuperServiceImpl;

import com.eastfair.certificate.service.CertificateUserService;
import com.eastfair.certificate.util.PBE_Cipher;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.model.CacheHashKey;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.core.utils.ImageUtil;
import com.eastfair.database.mybatis.conditions.Wraps;
import com.eastfair.database.mybatis.conditions.query.QueryWrap;
import com.eastfair.projectcore.entity.Dictionary;
import com.eastfair.security.util.DistionaryUtil;
import com.eastfair.venuebooking.api.ExhibitionManageFeign;
import com.eastfair.venueservice.dto.ExhibitionManageQuery;
import com.eastfair.venueservice.vo.ExhibitionManageVO;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;

import java.security.Security;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;

//import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.aop.framework.AopContext;
import com.eastfair.annotation.annotation.cache.Magic;
import com.eastfair.annotation.annotation.cache.Cache;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
//import com.baomidou.dynamic.datasource.annotation.DS;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.eastfair.certificate.vo.*;
import com.eastfair.certificate.dto.*;

import static com.eastfair.core.base.R.SUCCESS_CODE;

/**
 * <p>
 * 业务实现类
 * 证件模块
 * </p>
 *
 * @author ligang
 * @date 2022-12-20
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class BadgeTemplateServiceImpl extends SuperServiceImpl<BadgeTemplateMapper, BadgeTemplate> implements BadgeTemplateService {

    @Autowired
    BadgeTemplateDetailService badgeTemplateDetailService;

    @Autowired
    ExhibitionManageFeign exhibitionManageFeign;

    @Autowired
    CertificateUserService certificateUserService;

    @Autowired
    DistionaryUtil distionaryUtil;


    @Value("${com.eastfair.cipher}")
    private String cipher;

    /**
     * 处理新增相关处理
     *
     * @param model 实体
     * @return 是否成功
     */
    @Override
    public R<Boolean> handlerSave(BadgeTemplate model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        model.setTeamId(ContextUtil.getTeamId());
        model.setIsDeleted(BusinessConstant.NO);
        model.setIsEnabled(BusinessConstant.YES);
        //雪花ID
        return R.successDef();
    }

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<BadgeTemplate> modelList) {
        modelList.stream().forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    /**
     * 通用查询
     *
     * @param modelDTO DTO
     * @param ids      主键id集合
     * @return list
     */
    @Override
    public List<BadgeTemplate> list(BadgeTemplateDTO modelDTO, List<Long> ids) {
        return ((BadgeTemplateService) AopContext.currentProxy()).listOfCache(modelDTO, ids);
    }


    /**
     * 缓存查询
     *
     * @param modelDTO DTO
     * @param ids      主键id集合
     * @return list
     */
    @Override
    @Cache(key = "",
            magic = @Magic(
                    key = "{" +
                            "{'certificateId', #args[0]?.certificateId}," +
                            "{'exhibitionId', #args[0]?.exhibitionId}," +
                            "{'templateName', #args[0]?.templateName}," +
                            "{'templateType', #args[0]?.templateType}," +
                            "{'teamId', #args[0]?.teamId}," +
                            "{'isEnabled', #args[0]?.isEnabled}," +
                            "{'classify', #args[0]?.classify}," +
                            "{'id', #args[1]}" +
                            "}"))
    public List<BadgeTemplate> listOfCache(BadgeTemplateDTO modelDTO, List<Long> ids) {
        //查询
//        QueryWrapper<BadgeTemplate> queryWrapper = new QueryWrapper<>();
        BadgeTemplate badgeTemplate = new BadgeTemplate();
        if (modelDTO != null) {
            BeanUtils.copyProperties(modelDTO, badgeTemplate);
        }
        QueryWrap<BadgeTemplate> wrapper = Wraps.q(badgeTemplate);
//        if (modelDTO != null) {
//            queryWrapper.lambda().eq(modelDTO.getCertificateId() != null, BadgeTemplate::getCertificateId, modelDTO.getCertificateId());
//            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getTemplateName()), BadgeTemplate::getTemplateName, modelDTO.getTemplateName());
//            queryWrapper.lambda().eq(modelDTO.getTemplateType() != null, BadgeTemplate::getTemplateType, modelDTO.getTemplateType());
//            queryWrapper.lambda().eq(modelDTO.getTeamId() != null, BadgeTemplate::getTeamId, modelDTO.getTeamId());
//        }
        if (ids != null && !ids.isEmpty()) {
            wrapper.lambda().in(BadgeTemplate::getId, ids);
        }
        wrapper.lambda().eq(BadgeTemplate::getIsDeleted, BusinessConstant.DELETE_NO);
        List<BadgeTemplate> modelList = list(wrapper);
        return modelList;
    }


    @Override
    public BadgeTemplateVO saveOrUpdTemplate(BadgeTemplateDTO badgeTemplateDTO) {
        BadgeTemplate badgeTemplate = new BadgeTemplate();
        BeanUtils.copyProperties(badgeTemplateDTO, badgeTemplate);

        if (badgeTemplateDTO.getId() != null) {
            updateById(badgeTemplate);
        } else {
            save(badgeTemplate);
        }
        BadgeTemplateVO badgeTemplateVO = doToVo(badgeTemplate);
        List<BadgeTemplateDetailVO> badgeTemplateDetailVOList = badgeTemplateDetailService.saveOfList(badgeTemplate.getId(), badgeTemplateDetailService.assembleData(badgeTemplateDTO.getBadgeDetailJsonList()));
        badgeTemplateVO.setBadgeDetailJsonList(badgeTemplateDetailService.assembleDataOfJson(badgeTemplateDetailVOList));
        return badgeTemplateVO;
    }


    @Override
    public IPage<BadgeTemplateVO> pageVo(PageParams<BadgeTemplateDTO> params) {
        BadgeTemplateDTO badgeTemplateDTO = params.getModel();
        IPage<BadgeTemplate> page = params.buildPage();
        BadgeTemplate badgeTemplate = new BadgeTemplate();
        BeanUtils.copyProperties(badgeTemplateDTO, badgeTemplate);
//        QueryWrapper<BadgeTemplate> queryWrapper = new QueryWrapper<>();
//        queryWrapper.lambda()
//                .eq(badgeTemplateDTO.getCertificateId() != null, BadgeTemplate::getCertificateId, badgeTemplateDTO.getCertificateId())
//                .eq(badgeTemplateDTO.getExhibitionId() != null, BadgeTemplate::getExhibitionId, badgeTemplateDTO.getExhibitionId())
//                .like(StringUtils.isNotBlank(badgeTemplateDTO.getTemplateName()), BadgeTemplate::getTemplateName, "%" + badgeTemplateDTO.getTemplateName() + "%")
//                .eq(BadgeTemplate::getIsDeleted, BusinessConstant.NO);
        QueryWrap<BadgeTemplate> wrapper = Wraps.q(badgeTemplate);
        wrapper.lambda().eq(BadgeTemplate::getIsDeleted, BusinessConstant.NO);
        //page entity转vo
        IPage<BadgeTemplate> badgeTemplateIPage = page(page, wrapper);
        List<BadgeTemplateVO> badgeTemplateVOList = doToVos(badgeTemplateIPage.getRecords());
        if (!CollectionUtil.isEmpty(badgeTemplateVOList)) {
            assembleData(badgeTemplateVOList);
        }
        IPage<BadgeTemplateVO> badgeTemplateVOIPage = ConvertUtil.convertIPage(badgeTemplateIPage, badgeTemplateVOList);
        return badgeTemplateVOIPage;
    }

    @Override
    public BadgeTemplateVO detail(Long id) {
        BadgeTemplate badgeTemplate = getById(id);
        BadgeTemplateVO badgeTemplateVO = doToVo(badgeTemplate);
        BadgeTemplateDetailDTO badgeTemplateDetailDTO = new BadgeTemplateDetailDTO();
        badgeTemplateDetailDTO.setTemplateId(id);
        List<BadgeTemplateDetailVO> badgeTemplateDetailVOList = badgeTemplateDetailService.doToVos(badgeTemplateDetailService.list(badgeTemplateDetailDTO, null));
        badgeTemplateVO.setBadgeDetailJsonList(badgeTemplateDetailService.assembleDataOfJson(badgeTemplateDetailVOList));
        return badgeTemplateVO;
    }

    //筛选出布展和撤展
    public BadgeTemplate filterTemplate(List<BadgeTemplate> badgeTemplateList, CertificateUser certificateUser) {
        if (CollectionUtil.isEmpty(badgeTemplateList)) {
            return null;
        }
        if (certificateUser.getCertificateClassify() != null) {
            List<BadgeTemplate> badgeTemplateList2 =
                    badgeTemplateList.stream().filter(s -> s.getClassify() != null && certificateUser.getCertificateClassify().equals(s.getClassify().getCode())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(badgeTemplateList2)) {
                return badgeTemplateList2.get(0);
            }
        }
        return badgeTemplateList.get(0);
    }

    @Override
    public BadgeTemplateVO getPrintData(BadgeTemplateDTO badgeTemplateDTO) {
        //获取用户内容，并填充
        CertificateUser certificateUser = certificateUserService.getByIdCache(badgeTemplateDTO.getCertificateUserId());
        BadgeTemplateDTO badgeTemplateDTO1 = new BadgeTemplateDTO();
        badgeTemplateDTO1.setCertificateType(badgeTemplateDTO.getCertificateType());
//        badgeTemplateDTO1.setCertificateId(certificateUser.getCertificateId());
        List<BadgeTemplate> badgeTemplateList = list(badgeTemplateDTO1, null);
        if (CollectionUtil.isEmpty(badgeTemplateList)) {
            return null;
        }
        BadgeTemplateVO badgeTemplateVO = detail(filterTemplate(badgeTemplateList, certificateUser).getId());
        convertPersonPrintData(badgeTemplateVO, certificateUser);
//        badgeTemplateVO.setEncryptInfo(encrypt(1L, cipher));
        badgeTemplateVO.setEncryptInfo("12312JKL12J12LK3J2UISOFSN214KL23YDFDBCVUCNERWEREIVCBDFKWKERNSJFSLFDSJIU7892H2K33YJGDSKFSD1");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", "certificate");
        jsonObject.put("id", certificateUser.getId());
//        badgeTemplateVO.setQrCode(JSONObject.toJSONString(jsonObject));
        badgeTemplateVO.setQrCode("" + certificateUser.getId());
        return badgeTemplateVO;
    }


    /**
     * 加密
     *
     * @param key
     * @return
     */
    public String encrypt(Long key, String cipher) {
        try {
            Security.addProvider(new BouncyCastleProvider());
            byte[] decrypt = PBE_Cipher.decrypt(HexUtil.decodeHex(cipher));
            cipher = new String(decrypt);
            return SecureUtil.aes(cipher.getBytes()).encryptHex(key.toString());
        } catch (Exception exception) {
            exception.printStackTrace();
            return null;
        }
    }


    private BadgeTemplateVO convertPersonPrintData(BadgeTemplateVO badgeTemplateVO, CertificateUser certificateUser) {
        //默认添加相同属性名

        //组装公司展会业务数据
        List<CertificateUserVO> certificateUserVOList = new ArrayList<>();
        certificateUserVOList.add(certificateUserService.doToVo(certificateUser));
        certificateUserService.assembleBusinssData(certificateUserVOList);
        CertificateUserVO certificateUserVO = certificateUserVOList.get(0);

        log.info("组装公司展会业务数据 is {}", JSONObject.toJSONString(certificateUserVO));

        JSONObject jsonObject1 = JSONObject.parseObject(JSONObject.toJSONString(certificateUserVO));

        log.info("jsonObject1 is {}", jsonObject1);
        log.info("badgeDetailJsonList is {}", badgeTemplateVO.getBadgeDetailJsonList());

        for (JSONObject jsonObject : badgeTemplateVO.getBadgeDetailJsonList()) {
            for (String key : jsonObject1.keySet()) {
                if (key.equals(jsonObject.getString("field"))) {
                    jsonObject.put("value", jsonObject1.get(key));
                }
            }
        }
        log.info("初始化数据处理结束 ");
        log.info("jsonObject1 is {}", jsonObject1);
        log.info("badgeDetailJsonList is {}", badgeTemplateVO.getBadgeDetailJsonList());

        //额外数据
        for (JSONObject jsonObject : badgeTemplateVO.getBadgeDetailJsonList()) {
            switch (jsonObject.getString("field")) {
                case "spName":
                    if (jsonObject.get("value") == null) {
                        jsonObject.put("value", certificateUserVO.getFullName());
                    }
                    break;
                case "idCard":
                    if (jsonObject.get("value") == null) {
                        jsonObject.put("value", certificateUserVO.getCardNumber());
                    }
                    break;
                case "barCode":
                    if (jsonObject.get("value") == null) {
                        jsonObject.put("value", certificateUserVO.getCardNumber());
                    }
                    break;
                case "photoId":
                    //头像
                    if (jsonObject.get("value") == null) {
                        jsonObject.put("value", certificateUserVO.getWorkCertificateImg());
                    }
                    if (jsonObject.get("value") != null) {
                        //图片角度
                        int photo =0;
                        log.info("执行图片角度22 img is {}", certificateUserVO.getWorkCertificateImg());
//                        int photo = ImageUtil.getRotateAngleForPhoto(certificateUserVO.getWorkCertificateImg());
                        log.info("图片信息：{}, 角度：{}", certificateUserVO.getWorkCertificateImg(), photo);
                        jsonObject.put("orientation", photo);
                    }


                    break;
                case "qRCode":
                    //二维码
                    if (jsonObject.get("value") == null) {
                        JSONObject jsonObject2 = new JSONObject();
                        jsonObject2.put("type", "certificate");
                        jsonObject2.put("id", certificateUserVO.getId());
//                        jsonObject.put("value", JSONObject.toJSONString(jsonObject2));
                        jsonObject.put("value", "" + certificateUserVO.getId());
                    }
                    break;
                case "companyName":
                    //公司
                    if (jsonObject.get("value") == null) {
                        jsonObject.put("value", certificateUserVO.getServiceProviderVO() != null ? certificateUserVO.getServiceProviderVO().getCompanyName() : "");
                    }
                    break;
                case "mobilePhone":
                    //联系方式
                    if (jsonObject.get("value") == null) {
                        jsonObject.put("value", certificateUserVO.getContactInformation());
                    }
                    break;

                case "workCertificateImg":
                    //用户头像
                    if (jsonObject.get("value") == null) {
                        jsonObject.put("value", certificateUserVO.getWorkCertificateImg());
                    }
                    if (jsonObject.get("value") != null) {
                        //图片角度
                        int photo =0;
                        log.info("执行图片角度33  img is {}", certificateUserVO.getWorkCertificateImg());
//                        int photo = ImageUtil.getRotateAngleForPhoto(certificateUserVO.getWorkCertificateImg());
                        log.info("图片信息：{}, 角度：{}", certificateUserVO.getWorkCertificateImg(), photo);
                        jsonObject.put("orientation", photo);
                    }
                    break;
                case "exhibitionName":
                    //展会名称
                    if (jsonObject.get("value") == null) {
                        jsonObject.put("value", certificateUserVO.getExhibitionManageVO() != null ? certificateUserVO.getExhibitionManageVO().getExhibitionName() : "");
                    }
                    break;
                case "spaceName":
                    //场馆名称
                    if (jsonObject.get("value") == null) {
                        jsonObject.put("value", certificateUserVO.getExhibitionSpaceVO() != null ? certificateUserVO.getExhibitionSpaceVO().getSpaceName() : "");
                    }
                    break;
                case "booth":
                    //展位号
                    if (jsonObject.get("value") == null) {
                        jsonObject.put("value", certificateUserVO.getBooth());
                    }
                    break;
                case "comeInTime":
                    //申请进场日期
                    if (jsonObject.get("value") == null) {
//                        jsonObject.put("value", certificateUserVO.getAppointmentInStartTime());
                        if (certificateUserVO.getAppointmentInStartTime() != null) {
                            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                            String timestr = certificateUserVO.getAppointmentInStartTime().format(formatter);
                            log.info("timestr is {}", timestr);
                            jsonObject.put("value", timestr);
                        }


                    }
                    break;
                case "appointmentInEndTime":
                    //申请出场日期
                    if (jsonObject.get("value") == null) {
                        if (certificateUserVO.getAppointmentInEndTime() != null) {
                            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                            String timestr = certificateUserVO.getAppointmentInEndTime().format(formatter);
                            log.info("timestr is {}", timestr);
                            jsonObject.put("value", timestr);
                        }

                    }
                    break;

//                case "comminTime":
//                    //申请出场日期
//                    if (jsonObject.get("value") == null) {
//                        jsonObject.put("value", certificateUser.getContactInformation());
//                    }
//                    break;

                case "carNumber":
                    //车牌号
                    if (jsonObject.get("value") == null) {
                        jsonObject.put("value", certificateUserVO.getCarNumber());
                    }
                    break;
                case "workType":
                    //工种
                    if (StringUtils.isNotBlank(certificateUserVO.getWorkType())) {
                        log.info("执行工种 ");
                        jsonObject.put("value", distionaryUtil.getNameOfDict(certificateUserVO.getWorkType(), "WORK_TYPE"));
                        log.info("执行工种 结束");
                    }
                    break;

            }
        }
        return badgeTemplateVO;
    }

    public void assembleData(List<BadgeTemplateVO> badgeTemplateVOList) {
        ExhibitionManageQuery exhibitionManageQuery = new ExhibitionManageQuery();
        exhibitionManageQuery.setIds(badgeTemplateVOList.stream().map(BadgeTemplateVO::getExhibitionId).collect(Collectors.toList()));
        R<List<ExhibitionManageVO>> r = exhibitionManageFeign.queryAllExhibitionManage(exhibitionManageQuery);
        if (SUCCESS_CODE == r.getCode()) {
            List<ExhibitionManageVO> exhibitionManageVOList = r.getData();
            if (!CollectionUtil.isEmpty(exhibitionManageVOList)) {
                for (BadgeTemplateVO badgeTemplateVO : badgeTemplateVOList) {
                    for (ExhibitionManageVO exhibitionManageVO : exhibitionManageVOList) {
                        if (exhibitionManageVO.getId().equals(badgeTemplateVO.getExhibitionId())) {
                            badgeTemplateVO.setExhibitionName(exhibitionManageVO.getExhibitionName());
                        }
                    }
                }
            }
        }
    }

    @Override
    public List<JSONObject> assembleDataVO(List<BadgeTemplateVO> badgeTemplateVOList) {
        //转换对象
        List<JSONObject> jsonObjectList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(badgeTemplateVOList)) {
            for (BadgeTemplateVO badgeTemplateVO : badgeTemplateVOList) {
                JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(badgeTemplateVO));
                JSONObject styleJson = JSONObject.parseObject(badgeTemplateVO.getStyleTxt());
                for (String key : styleJson.keySet()) {
                    Object object = jsonObject.get(key);
                    if (object == null) {
                        jsonObject.put(key, styleJson.get(key));
                    }
                }
                jsonObject.put("classify", badgeTemplateVO.getClassify() != null ? badgeTemplateVO.getClassify().getCode() : "");
                jsonObject.remove("styleTxt");
                jsonObjectList.add(jsonObject);
            }
        }
        return jsonObjectList;
    }


    /**
     * do转vo
     *
     * @param model model
     * @return modelVo
     */
    @Override
    public BadgeTemplateVO doToVo(BadgeTemplate model) {
        BadgeTemplateVO modelVo = new BadgeTemplateVO();
        BeanUtils.copyProperties(model, modelVo);
        modelVo.setId(model.getId());
        return modelVo;
    }

    /**
     * do转vo
     *
     * @param modelList modelList
     * @return list
     */
    @Override
    public List<BadgeTemplateVO> doToVos(List<BadgeTemplate> modelList) {
        if (modelList == null || modelList.isEmpty()) {
            return null;
        }
        List<BadgeTemplateVO> result = new ArrayList<>();
        for (BadgeTemplate model : modelList) {
            result.add(doToVo(model));
        }
        return result;
    }
}
